//
// Created by tong on 9/27/24.
//

#pragma once
#include <string>
#include <vector>
#include <fstream>

#include "Primitive.h"

/**
 * 网格原始数据解析
 */

namespace GRDECLKeyWords {
    // 原始GRDECL文件关键字
    constexpr char const SPECGRID[] = "SPECGRID";
    constexpr char const COORD[] = "COORD";
    constexpr char const ZCORN[] = "ZCORN";
    constexpr char const ACTNUM[] = "ACTNUM";
    constexpr char const YOUNGMOD[] = "YOUNGMOD";
    constexpr char const PIOSSON[] = "POISSONR";
    constexpr char const PORO[] = "PORO";
    constexpr char const ROCKDEN[] = "ROCKDEN";
}

// GRDECL文件解析器
namespace GRDECLParser {
    // 读取关键字数据
    // 输入：文件流
    bool moveToKeyWordData(std::ifstream &is);
    // 跳过注释
    // 输入：文件流
    void skipComment(std::ifstream &is);
    // 移动至下一个关键字
    // 输入：文件流
    bool moveToNextKeyWord(std::ifstream &is);
    // 读取数据模板
    // 输入：文件流，数据容器
    template<typename T>
    void readData(std::ifstream &is,vector<T>&);
}

// GRDECL原始数据
struct  GRDECLRawData {
    // IJK 维度
    int dimI=0;
    int dimJ=0;
    int dimK=0;
    // Pillar起止点Raw数据
    DoubleList coord;
    // 角点深度数据
    DoubleList zcoord; 
    // 活网格标记
    BoolList actnum; 
    // 材料参数
    DoubleList Poisson_;
    DoubleList YoungsMod_;
    DoubleList Porosity_;
    DoubleList RockDensity_;
    GRDECLRawData() = delete;
    // RAII 构造函数
    // 输入：GRDECL原始数据文件路径
    explicit GRDECLRawData(const std::string& filePath,const std::string& dataPath="");
    void freeData();
};

// 赛题2 RAW网格顶点数据
struct  PointFieldMesh {
    // 网格顶点数据
    PointList points_;
    // 结点上的数据
    DoubleList data_;

    int nX;
    int nY;
    int nZ;
    int nCell;

    PointFieldMesh() = delete;
    // RAII 构造函数
    // 输入：GRDECL原始数据文件路径
    explicit PointFieldMesh(const std::string& filePath);
    // 计算网格维度数据
    void calcNodeDim();
    // 输出VTK格式网格顶点数据
    void vtkCellNodeDataWriter(const std::string &outputPath,const DoubleList& data);
    // 输出赛题要求的数据
    void writeRequiredData(const std::string& outputPath);

};